//
//  PushViewController.swift
//  JKTools
//
//  Created by 姜奎 on 2024/11/1.
//

import Cocoa

class PushViewController: NSViewController {

    @IBOutlet weak var p8CerPathTextField: NSTextField!

    @IBOutlet weak var keyIDTextField: NSTextField!

    @IBOutlet weak var teamIDTextField: NSTextField!

    @IBOutlet weak var bundleIDTextField: NSTextField!

    @IBOutlet weak var deviceTokenTextField: NSTextField!
    
    @IBOutlet weak var prioritySwitch: NSSegmentedControl!

    @IBOutlet weak var payloadTypeSwitch: NSPopUpButton!
    
    @IBOutlet weak var payloadBodySwitch: NSPopUpButton!

    @IBOutlet var payloadBodyTextView: NSTextView!
    
    @IBOutlet var sendLogTextView: NSTextView!

    @IBOutlet weak var modeSwitch: NSMatrix!

    @IBOutlet weak var devSelect: NSButtonCell!
    
    @IBOutlet weak var pushBtn: NSButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        guard let lastInfo = LastPushInfo.read() else {
            return
        }

        self.p8CerPathTextField.stringValue = lastInfo.p8CerPath
        self.keyIDTextField.stringValue = lastInfo.keyID
        self.teamIDTextField.stringValue = lastInfo.teamID
        self.bundleIDTextField.stringValue = lastInfo.bundleID
        self.deviceTokenTextField.stringValue = lastInfo.deviceToken
        self.payloadBodyTextView.string = lastInfo.payloadBody
    }
    
    @IBAction func selectP8CerBtnAction(_ sender: NSButton) {
        NSOpenPanel.open { filePath in
            guard let filePath = filePath else {
                return
            }
            self.p8CerPathTextField.stringValue = filePath.path
        }
    }


    @IBAction func payloadBodyTouched(_ sender: NSPopUpButton?) {
        var stringValue  = "{\"aps\":{\"alert\":\"This is some fancy message.\",\"badge\":6,\"sound\": \"default\"}}"
        guard let sender = sender else {
            payloadBodyTextView.string = stringValue
            return
        }
        switch sender.indexOfSelectedItem {
        case 1: stringValue = "{\"aps\":{\"alert\":\"This is some fancy message.\"}}"
        case 2: stringValue = "{\"aps\":{\"alert\":\"This is some fancy message.\",\"badge\":6}}"
        default: break
        }
        payloadBodyTextView.string = stringValue
    }
    
    @IBAction func push(_ sender: NSButton) {
        let p8CerPath = p8CerPathTextField.stringValue
        guard p8CerPath.isEmpty == false else {
            Alert.alert(message: "请输入p8证书地址", buttons: ["知道了"]) { _ in
                self.p8CerPathTextField.becomeFirstResponder()
            }
            return
        }
        let keyID = keyIDTextField.stringValue
        guard keyID.isEmpty == false else {
            Alert.alert(message: "请输入KeyID", buttons: ["知道了"]) { _ in
                self.keyIDTextField.becomeFirstResponder()
            }
            return
        }
        let teamID = teamIDTextField.stringValue
        guard teamID.isEmpty == false else {
            Alert.alert(message: "请输入TeamID", buttons: ["知道了"]) { _ in
                self.teamIDTextField.becomeFirstResponder()
            }
            return
        }
        let bundleID = bundleIDTextField.stringValue
        guard bundleID.isEmpty == false else {
            Alert.alert(message: "请输入BundleID", buttons: ["知道了"]) { _ in
                self.bundleIDTextField.becomeFirstResponder()
            }
            return
        }
        let deviceToken = deviceTokenTextField.stringValue
        guard deviceToken.isEmpty == false else {
            Alert.alert(message: "请输入DeviceToken", buttons: ["知道了"]) { _ in
                self.deviceTokenTextField.becomeFirstResponder()
            }
            return
        }
        let payloadBody = payloadBodyTextView.string
        guard payloadBody.isEmpty == false else {
            Alert.alert(message: "请输入消息体", buttons: ["知道了"]) { _ in
                self.payloadBodyTouched(nil)
                self.payloadBodyTextView.becomeFirstResponder()
            }
            return
        }

        LastPushInfo(p8CerPath: p8CerPath, keyID: keyID, teamID: teamID, bundleID: bundleID, deviceToken: deviceToken, payloadBody: payloadBody).save()

        let pem = P8Pem(path: p8CerPath, keyID: keyID, teamID: teamID)

        Task {
            sender.isEnabled = false
            do {
                let token = try pem.generatePushToken(bundleID: bundleID)
                print("token:\(token)")
                let inSandbox = modeSwitch.selectedCell()!.tag == 1
                let (a,_) = try await URLSession.post(payload: payloadBody, token: token, topic: bundleID, priority: prioritySwitch.selectedTag(), collapseID: "", payloadType: payloadTypeSwitch.selectedItem!.title, inSandbox:inSandbox)

                let message = """
                                        P8证书：\(p8CerPath)
                                        KeyID：\(keyID)
                                        inSandbox：\(inSandbox)
                                        TeamID：\(teamID)
                                        BundleID：\(bundleID)
                                        DeviceToken：\(deviceToken)
                                        消息体：
                                        \(payloadBody)
                                        Response：\(a.toString() ?? "")
                                        """
                showMessage(message)
            } catch {
                showMessage("\(error)")
            }

            sender.isEnabled = true
        }

        func showMessage(_ message: String) {
            sendLogTextView.string = message
            let range = NSRange(location: sendLogTextView.string.utf16.count, length: 0)
                    // 滚动到该范围可见
            sendLogTextView.scrollRangeToVisible(range)
        }
    }
}

struct LastPushInfo: Codable {

    static let SaveKey = "LastPushInfoSaveKey"

    let p8CerPath: String
    let keyID: String
    let teamID: String
    let bundleID: String
    let deviceToken: String
    let payloadBody: String

    func save() {
        guard let data = try? JSONEncoder().encode(self) else {
            return
        }
        UserDefaults.standard.set(data, forKey: LastPushInfo.SaveKey)
    }

    static func read() -> LastPushInfo? {
        guard let data = UserDefaults.standard.data(forKey: LastPushInfo.SaveKey) else { return nil }

        guard let info = try? JSONDecoder().decode(LastPushInfo.self, from: data) else { return nil }

        return info
    }
}
